<template>
  <div>
    <!-- 生产源名称 -->
    <div class="source-info">
      <p>
        <span>生产源名称：</span>
        <a href="javascript:void(0)" class="source-link">{{ selectedSourceName }}</a>
      </p>
    </div>

    <!-- 选择索引模板 -->
    <div class="template-section">
      <div class="tpl-label"><span class="req">*</span>选择索引模板：</div>
      <a-radio-group v-model:value="tplValue" button-style="solid" class="tpl-group">
        <a-radio-button value="综合">综合</a-radio-button>
        <a-radio-button value="新闻">新闻</a-radio-button>
        <a-radio-button value="百科">百科</a-radio-button>
        <a-radio-button value="图片">图片</a-radio-button>
        <a-radio-button value="视频">视频</a-radio-button>
        <a-radio-button value="自定义">自定义</a-radio-button>
      </a-radio-group>
    </div>

    <!-- 数据同步策略 -->
    <div class="sync-section">
      <div class="sync-title"><span class="req">*</span>数据同步策略：</div>

      <a-tabs type="card" class="sync-tabs" :activeKey="activeTab" @change="onTabChange">
        <a-tab-pane key="regex" tab="正则匹配" />
      </a-tabs>

      <div class="sync-params">
        <a-form layout="vertical" class="sync-form">
          <div class="sync-row">
            <a-form-item label="同步策略传参" :required="true" class="sync-item">
              <a-input :value="strategyForm.datasync_paras" style="width: 100%"
                placeholder="正则表达式，如：&lt;video[^&gt;]*&gt;.*?&lt;/video&gt;|(&lt;iframe[^&gt;]*src=['&quot;][^'&quot;]*[^&gt;]*&gt;.*?&lt;/iframe&gt;)"
                @update:value="(v) => setStrategyField('datasync_paras', String(v ?? ''))" />
            </a-form-item>

            <a-form-item label="时间同步策略" :required="true" class="sync-item">
              <a-select v-model:value="timeStrategy" style="width: 100%">
                <a-select-option value="manual">手动更新</a-select-option>
              </a-select>
            </a-form-item>
          </div>
        </a-form>
      </div>
    </div>

    <!-- ===== 倒排索引 Mapping 配置 ===== -->
    <div class="mapping-config">
      <a-form layout="vertical" class="mapping-validate">
        <a-form-item label="倒排索引Mapping配置" required :validate-status="mappingValidateStatus"
          :help="mappingValidateHelp">
          <a-table :dataSource="mappingData" :columns="mappingColumns" rowKey="uid" bordered class="custom-table"
            :pagination="false" :scroll="{ x: 'max-content' }" :loading="mappingLoading" :rowClassName="rowClassName">
            <template #bodyCell="{ text, record, column }">
              <!-- 内联可编辑列（当 isIndexed 为“否”时禁用点击） -->
              <template v-if="inlineEditableCols.includes(column.key)">
                <template v-if="editing.id === record.uid && editing.field === column.key">
                  <a-input-number v-if="editing.field === 'permission'" :value="editingNumber" :min="0" :max="100"
                    :precision="0" :controls="false" size="small" autofocus class="perm-input" placeholder="0-100"
                    @update:value="setEditingNumber" @blur="onEditBlur(record)" @pressEnter="onEditPressEnter(record)"
                    @keydown.esc.prevent="onEditCancel" />
                  <a-input v-else :value="editingValue" size="small" autofocus @update:value="setEditingValue"
                    @blur="onEditBlur(record)" @pressEnter="onEditPressEnter(record)"
                    @keydown.esc.prevent="onEditCancel" />
                </template>
                <template v-else>
                  <span class="editable-cell" :class="{ 'disabled-cell': !canEditRow(record) }"
                    :style="{ cursor: canEditRow(record) ? 'text' : 'not-allowed' }"
                    @click="canEditRow(record) && startEdit(record, column.key)">
                    {{
                      column.key === 'permission'
                        ? (record.permission ?? '—')
                        : (record as any)[column.key] || '—'
                    }}
                  </span>
                </template>
              </template>

              <!-- 下拉列（当 isIndexed 为“否”时禁用；但 isIndexed 自己永远可点） -->
              <template v-else-if="dropdownCols.includes(column.key)">
                <a-dropdown :trigger="isDropdownDisabled(record, column.key) ? [] : ['click']"
                  :overlayClassName="column.key === 'fieldName' ? 'fieldname-overlay' : ''"
                  :getPopupContainer="column.key === 'fieldName' ? getClosestTableBody : undefined"
                  placement="bottomLeft">
                  <span class="datatype-trigger" @click.prevent
                    :class="[{ 'disabled-trigger': isDropdownDisabled(record, column.key) }, { 'is-indexed-cell': column.key === 'isIndexed' }]"
                    :style="triggerStyle(record, column.key)">
                    <template v-if="record[column.key]">
                      <!-- “是否索引” 显示为 是/否，并着色：是=绿色，否=黑色 -->
                      <span class="datatype-text" :style="{
                        color: column.key === 'isIndexed'
                          ? (toYes(record[column.key]) === '是' ? '#52c41a' : '#000000')
                          : '#000000'
                      }">
                        {{ column.key === 'isIndexed' ? toYes(record[column.key]) : record[column.key] }}
                      </span>
                      <span class="triangle"></span>
                    </template>
                    <template v-else>
                      <span class="triangle triangle-only"></span>
                    </template>
                  </span>
                  <template #overlay>
                    <a-menu
                      @click="({ key }) => { if (!isDropdownDisabled(record, column.key)) onDropdownSelect(record, column.key, String(key)); }">
                      <a-menu-item v-for="opt in dropdownOptions[column.key]" :key="opt">{{ opt }}</a-menu-item>
                    </a-menu>
                  </template>
                </a-dropdown>
              </template>

              <!-- 操作列 -->
              <span v-else-if="column.key === 'operation'">
                <a href="javascript:void(0)" class="advanced-config-link">高级配置</a>
              </span>

              <!-- 其它列默认展示 -->
              <span v-else>{{ text }}</span>
            </template>
          </a-table>
        </a-form-item>
      </a-form>

      <div class="add-row-container">
        <a-button type="dashed" class="add-row-button" @click="addRow">
          <svg class="add-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16">
            <path d="M8 1v14M1 8h14" stroke="#1890ff" stroke-width="2" fill="none" stroke-linecap="round"
              stroke-linejoin="round" />
          </svg>
          增加行
        </a-button>
      </div>
    </div>

    <!-- ===== 向量索引 Mapping 配置 ===== -->
    <div class="mapping-config">
      <a-form layout="vertical">
        <a-form-item label="向量索引Mapping配置" required :validate-status="vectorValidateStatus" :help="vectorValidateHelp">
          <a-table :dataSource="vectorMappingData" :columns="vectorMappingColumns" rowKey="uid" bordered
            class="custom-table" :pagination="false" :scroll="{ x: 'max-content' }" :loading="mappingLoading"
            :rowClassName="rowClassName">
            <template #bodyCell="{ text, record, column }">
              <!-- 行内编辑（若 isIndexed 为“否”则禁用；但 isIndexed 自身不在此分支） -->
              <template v-if="vectorInlineEditableCols.includes(column.key)">
                <template v-if="editing.id === record.uid && editing.field === column.key">
                  <a-input-number v-if="editing.field === 'weight'" :value="editingNumber" :min="0" :max="100"
                    :precision="0" :controls="false" size="small" autofocus class="perm-input" placeholder="0-100"
                    @update:value="setEditingNumber" @blur="onEditBlur(record)" @pressEnter="onEditPressEnter(record)"
                    @keydown.esc.prevent="onEditCancel" />
                  <a-input v-else :value="editingValue" size="small" autofocus @update:value="setEditingValue"
                    @blur="onEditBlur(record)" @pressEnter="onEditPressEnter(record)"
                    @keydown.esc.prevent="onEditCancel" />
                </template>
                <template v-else>
                  <span class="editable-cell" :class="{ 'disabled-cell': !canEditRow(record) }"
                    :style="{ cursor: canEditRow(record) ? 'text' : 'not-allowed' }"
                    @click="canEditRow(record) && startEdit(record, column.key)">
                    {{
                      column.key === 'weight'
                        ? (record.weight ?? '—')
                        : (record as any)[column.key] || '—'
                    }}
                  </span>
                </template>
              </template>

              <!-- 下拉列（若 isIndexed 为“否”则禁用；但 isIndexed 自己永远可点） -->
              <template v-else-if="vectorDropdownCols.includes(column.key)">
                <a-dropdown :trigger="isDropdownDisabled(record, column.key) ? [] : ['click']"
                  :overlayClassName="column.key === 'fieldName' ? 'fieldname-overlay' : ''"
                  :getPopupContainer="column.key === 'fieldName' ? getClosestTableBody : undefined"
                  placement="bottomLeft">
                  <span class="datatype-trigger" @click.prevent
                    :class="[{ 'disabled-trigger': isDropdownDisabled(record, column.key) }, { 'is-indexed-cell': column.key === 'isIndexed' }]"
                    :style="triggerStyle(record, column.key)">
                    <template v-if="record[column.key]">
                      <span class="datatype-text" :style="{
                        color: column.key === 'isIndexed'
                          ? (toYes(record[column.key]) === '是' ? '#52c41a' : '#000000')
                          : '#000000'
                      }">
                        {{ column.key === 'isIndexed' ? toYes(record[column.key]) : record[column.key] }}
                      </span>
                      <span class="triangle"></span>
                    </template>
                    <template v-else>
                      <span class="triangle triangle-only"></span>
                    </template>
                  </span>
                  <template #overlay>
                    <a-menu
                      @click="({ key }) => { if (!isDropdownDisabled(record, column.key)) onDropdownSelect(record, column.key, String(key)); }">
                      <a-menu-item v-for="opt in vectorDropdownOptions[column.key]" :key="opt">
                        {{ opt }}
                      </a-menu-item>
                    </a-menu>
                  </template>
                </a-dropdown>
              </template>

              <span v-else>{{ text }}</span>
            </template>
          </a-table>
        </a-form-item>
      </a-form>

      <div class="add-row-container">
        <a-button type="dashed" class="add-row-button" @click="addVectorRow">
          <svg class="add-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16">
            <path d="M8 1v14M1 8h14" stroke="#1890ff" stroke-width="2" fill="none" stroke-linecap="round"
              stroke-linejoin="round" />
          </svg>
          增加行
        </a-button>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { computed, ref } from 'vue'

const props = defineProps<{
  selectedSourceName: string
  strategyForm: { datasync_strategy: string; datasync_paras: string }

  mappingData: any[]
  mappingColumns: any[]
  mappingLoading: boolean

  inlineEditableCols: readonly string[]
  dropdownCols: readonly string[]
  dropdownOptions: Record<string, string[]>

  editing: { id: string | null; field: string | null }
  editingValue: string
  editingNumber: number | null

  mappingValidateStatus: any
  mappingValidateHelp: string

  addRow: () => void
  startEdit: (record: any, field: string) => void
  onEditBlur: (record: any) => void
  onEditPressEnter: (record: any) => void
  onEditCancel: () => void
  onDropdownSelect: (record: any, field: string, value: string) => void

  setEditingNumber: (v: number | null) => void
  setEditingValue: (v: string) => void
  setStrategyField: (key: 'datasync_strategy' | 'datasync_paras', v: string) => void

  /* 向量索引 */
  vectorMappingData: any[]
  vectorMappingColumns: any[]
  vectorInlineEditableCols: readonly string[]
  vectorDropdownCols: readonly string[]
  vectorDropdownOptions: Record<string, string[]>
  addVectorRow: () => void
}>()

/* 选择索引模板 */
const tplValue = ref<'综合' | '新闻' | '百科' | '图片' | '视频' | '自定义'>('新闻')

/* Tabs 激活项 */
const activeTab = ref<'regex'>('regex')
const onTabChange = (_: string) => {
  activeTab.value = 'regex'
  props.setStrategyField('datasync_strategy', 'regex')
}

/* 时间同步策略 */
const timeStrategy = ref<'manual'>('manual')

const getClosestTableBody = (triggerNode: HTMLElement) =>
  (triggerNode?.closest?.('.ant-table-body') as HTMLElement) || document.body

/* —— 是否索引：统一“是/否”显示 —— */
const toYes = (v: any) => {
  if (v === '是' || v === '否') return v
  if (v === true || v === 'true' || v === 'Y' || v === 1) return '是'
  return '否'
}
const canEditRow = (record: any) => toYes(record?.isIndexed) === '是'
const isDropdownDisabled = (record: any, key: string) => {
  if (key === 'isIndexed') return false
  return !canEditRow(record)
}
const triggerStyle = (record: any, key: string) => {
  const disabled = isDropdownDisabled(record, key)
  return {
    cursor: disabled ? 'not-allowed' : 'pointer',
    pointerEvents: disabled ? 'none' : 'auto'
  }
}
const rowClassName = (record: any) => (canEditRow(record) ? '' : 'row-disabled')

/* —— 向量表单校验（保持原样） —— */
const VECTOR_REQUIRED_FIELDS = ['fieldName', 'dataType', 'isIndexed', 'index_field_name', 'indexType'] as const
const isBlank = (v: any) => {
  const s = String(v ?? '').trim()
  return !s || s === '—'
}
const vectorFirstError = computed(() => {
  const rows = (props.vectorMappingData || []) as any[]
  if (!rows.length) return ''
  for (let i = 0; i < rows.length; i++) {
    const r: any = rows[i]
    const allEmpty = VECTOR_REQUIRED_FIELDS.every((k) => isBlank(r?.[k]))
    if (allEmpty) continue
    for (const k of VECTOR_REQUIRED_FIELDS) {
      if (isBlank(r?.[k])) {
        const labelMap: Record<string, string> = {
          fieldName: '生产源字段名称',
          dataType: '数据类型',
          isIndexed: '是否索引',
          index_field_name: '索引字段名称',
          indexType: '索引类型',
        }
        return `第 ${i + 1} 行（向量）「${labelMap[k]}」未填写`
      }
    }
  }
  return ''
})
const vectorIsValid = computed(() => !vectorFirstError.value)
const vectorValidateStatus = computed(() => (vectorIsValid.value ? undefined : 'error'))
const vectorValidateHelp = computed(() => (vectorIsValid.value ? '' : vectorFirstError.value))
</script>

<style scoped lang="less">
@blue-weak: #e6f7ff;
@text-dark: #262626;

/* 生产源信息 */
.source-info {
  margin-bottom: 16px;
}

.source-info p span {
  color: #858b9b;
  font-size: 14px;
  line-height: 20px;
}

.req {
  color: #f5222d;
  margin-right: 4px;
}

/* 选择索引模板 */
.template-section {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-bottom: 12px;

  .tpl-label {
    font-size: 14px;
    color: @text-dark;
  }

  .tpl-group :deep(.ant-radio-button-wrapper) {
    height: 32px;
    line-height: 30px;
    margin: 0 10px;
  }
}

/* 数据同步策略 */
.sync-section {
  margin-bottom: 16px;
}

.sync-title {
  font-size: 14px;
  color: @text-dark;
  margin-bottom: 6px;
}

.sync-params {
  background: #f5f6f8;
  border: 1px solid #eee;
  border-radius: 4px;
  padding: 12px;
}

.sync-form {
  margin: 0;
}

.sync-row {
  display: flex;
  gap: 24px;
}

.sync-item {
  flex: 1 1 0;
}

.sync-form :deep(.ant-form-item) {
  margin-bottom: 0;
}

@media (max-width: 992px) {
  .sync-row {
    flex-direction: column;
    gap: 12px;
  }
}

.sync-tabs :deep(.ant-tabs-nav) {
  margin: 0 0 12px;
}

.sync-tabs :deep(.ant-tabs-tab) {
  height: 32px;
  line-height: 32px;
}

.sync-tabs :deep(.ant-tabs-tab-active) {
  font-weight: 500;
}

/* 表头行高 */
.custom-table :deep(.ant-table-thead > tr > th) {
  height: 40px !important;
  background: #f4f8fd !important;
  padding-top: 0 !important;
  padding-bottom: 0 !important;
  line-height: 40px !important;
}

/* 只给非测量行设置行高 */
.mapping-config .custom-table:deep(.ant-table-tbody > tr:not(.ant-table-measure-row):not(.ant-table-row-measure) > td) {
  height: 40px !important;
  line-height: 40px !important;
  padding-top: 0 !important;
  padding-bottom: 0 !important;
}

/* 隐藏测量行 */
.mapping-config .custom-table :deep(.ant-table-tbody > tr.ant-table-measure-row),
.mapping-config .custom-table :deep(.ant-table-tbody > tr.ant-table-row-measure),
.mapping-config .custom-table :deep(.ant-table-tbody > tr[style*="height: 0px"]) {
  display: none !important;
  height: 0 !important;
  overflow: hidden !important;
}

/* 行单元格归零 */
.mapping-config .custom-table:deep(.ant-table-tbody > tr.ant-table-measure-row > td),
.mapping-config .custom-table:deep(.ant-table-tbody > tr.ant-table-row-measure > td),
.mapping-config .custom-table:deep(.ant-table-tbody > tr[style*="height: 0px"] > td) {
  height: 0 !important;
  line-height: 0 !important;
  padding: 0 !important;
  border: 0 !important;
}

/* 行置灰样式（当 是否索引=否，整行灰） */
.custom-table :deep(.row-disabled td) {
  color: #bfbfbf !important;
  background: #f7f7f7 !important;
}

.custom-table :deep(.row-disabled .editable-cell) {
  cursor: not-allowed !important;
}

.disabled-cell {
  color: #bfbfbf;
}

.disabled-trigger {
  color: #bfbfbf;
}

/* 关键：整行灰时，“是否索引”这一格仍可点，且显示颜色按 是/否 控制（是=绿、否=黑） */
.custom-table :deep(.row-disabled td .is-indexed-cell),
.custom-table :deep(.row-disabled td .is-indexed-cell .datatype-text) {
  filter: none !important;
  opacity: 1 !important;
  cursor: pointer !important;
  pointer-events: auto !important;
  color: inherit !important;
  /* 文本颜色由内联样式控制成绿/黑 */
}

/* 其它样式 */
.editable-cell {
  cursor: text;
  display: inline-block;
  min-height: 22px;
  padding: 2px 4px;

  &:hover {
    background: #f5f5f5;
    border-radius: 4px;
  }
}

.perm-input {
  width: 120px;
}

/* 下拉触发样式 */
.datatype-trigger {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  cursor: pointer;
  user-select: none;
  min-height: 22px;
  padding: 2px 4px;

  &:hover {
    background: #f5f5f5;
    border-radius: 4px;
  }
}

.datatype-text {
  line-height: 1;
}

.triangle {
  width: 0;
  height: 0;
  border-left: 5px solid transparent;
  border-right: 5px solid transparent;
  border-top: 6px solid #5a5a5a;
  display: inline-block;
  transform: translateY(1px);
}

.triangle-only {
  margin-left: 0;
}

/* 增加行按钮容器 */
.add-row-container {
  position: static;
  margin: 40px;
  display: flex;
  justify-content: center;
  background: transparent;
  border-top: none;
  box-shadow: none;
}

.add-row-button {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 36px;
  padding: 0 16px;
  border-radius: 6px;
}

.add-icon {
  vertical-align: middle;
}
</style>

<style lang="less">
.fieldname-overlay .ant-dropdown-menu {
  max-height: 256px;
  overflow-y: auto;
  overscroll-behavior: contain;
}
</style>
